home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Games / SprocketInvaders / Source / Sprite.c < prev    next >
Encoding:
Text File  |  2000-09-28  |  5.5 KB  |  240 lines  |  [TEXT/MPS ]

  1. //•    ------------------------------------------------------------------------------------------    •
  2. //•
  3. //•    Copyright © 1996 Apple Computer, Inc., All Rights Reserved
  4. //•
  5. //•
  6. //•        You may incorporate this sample code into your applications without
  7. //•        restriction, though the sample code has been provided "AS IS" and the
  8. //•        responsibility for its operation is 100% yours.  However, what you are
  9. //•        not permitted to do is to redistribute the source as "DSC Sample Code"
  10. //•        after having made changes. If you're going to re-distribute the source,
  11. //•        we require that you make it clear in the source that the code was
  12. //•        descended from Apple Sample Code, but that you've made changes.
  13. //•
  14. //•        Authors:
  15. //•            Chris De Salvo
  16. //•
  17. //•    ------------------------------------------------------------------------------------------    •
  18.  
  19. //•    ------------------------------    Includes
  20.  
  21. #include <Resources.h>
  22.  
  23. #include "Blitter.h"
  24. #include "ErrorHandler.h"
  25. #include "MemoryHandler.h"
  26. #include "Sprite.h"
  27.  
  28. //•    ------------------------------    Private Definitions
  29.  
  30. #define kSpriteResType                'SPRT'
  31.  
  32. //•    ------------------------------    Private Types
  33. //•    ------------------------------    Private Variables
  34. //•    ------------------------------    Private Functions
  35.  
  36. static void NewFramesFromPtr(SpritePtr theSprite, Ptr theData, UInt32 numFrames);
  37.  
  38. //•    ------------------------------    Public Variables
  39. //•    --------------------    SpriteLoad
  40.  
  41. SpritePtr
  42. SpriteLoad(SInt16 resNum)
  43. {
  44. SpritePtr    theSprite;
  45. Handle        theHandle;
  46. UInt16        numFrames;
  47. Ptr            index;
  48.  
  49.     theHandle = GetResource(kSpriteResType, resNum);
  50.     if (! theHandle)
  51.         return (nil);
  52.  
  53.     theSprite = (SpritePtr) NewPtrClear(sizeof (Sprite));
  54.     if (! theSprite)
  55.         return (nil);
  56.         
  57.     HLockHi(theHandle);
  58.     index = *theHandle;
  59.     
  60.     numFrames = *((UInt16 *) index);
  61.     index += 2;
  62.  
  63.     theSprite->frames = (FramePtr *) NewTaggedPtrClear(numFrames * sizeof (FramePtr), 'FPTR', resNum);
  64.     if (! theSprite->frames)
  65.     {
  66.         HUnlock(theHandle);
  67.         return (nil);
  68.     }
  69.     
  70.     theSprite->numFrames = numFrames;
  71.  
  72.     NewFramesFromPtr(theSprite, index, numFrames);
  73.     DisposeHandleZ(&theHandle);
  74.     
  75.     return (theSprite);
  76. }
  77.  
  78. //•    --------------------    NewFramesFromPtr
  79.  
  80. static void
  81. NewFramesFromPtr(SpritePtr theSprite, Ptr theData, UInt32 numFrames)
  82. {
  83. int        i;
  84. UInt16    h, w;
  85. SInt16    hotX, hotY;
  86.  
  87.     for (i = 0; i < numFrames; i++)
  88.     {
  89.         w = * ((UInt16 *) theData);
  90.         theData += 2;
  91.         
  92.         h = * ((UInt16 *) theData);
  93.         theData += 2;
  94.         
  95.         hotX = * ((SInt16 *) theData);
  96.         theData += 2;
  97.         
  98.         hotY = * ((SInt16 *) theData);
  99.         theData += 2;
  100.  
  101.         theSprite->frames[i] = (FramePtr) NewTaggedPtrClear(sizeof (Frame), 'FRAM', 1);
  102.         if (! theSprite->frames[i])
  103.             FatalError("Could not allocate sprite frame.");
  104.         
  105.         theSprite->frames[i]->width = w;
  106.         theSprite->frames[i]->height = h;
  107.         theSprite->frames[i]->hotX = hotX;
  108.         theSprite->frames[i]->hotY = hotY;
  109.         
  110.         theSprite->frames[i]->image = (UInt8 *) NewTaggedPtrClear(w * h, 'IMAG', i);
  111.         if (! theSprite->frames[i]->image)
  112.             FatalError("Could not allocate sprite frame bits.");
  113.             
  114.         BlockMoveData(theData, theSprite->frames[i]->image, w * h);
  115.         
  116.         theData += w * h;
  117.     }
  118. }
  119.  
  120. //•    --------------------    SpriteDraw
  121.  
  122. Rect
  123. SpriteDraw(SpritePtr theSprite, UInt32 frameNum, CGrafPtr dest, SInt32 x, SInt32 y)
  124. {
  125. FramePtr    theFrame;
  126. Rect        blitRect;
  127. Rect        emptyRect = { 0, 0, 0, 0 };
  128. UInt32        h = 0, v = 0;
  129.  
  130.     theFrame = theSprite->frames[frameNum];
  131.  
  132.     //•    Set up a rectangle inside the image area that is clipped to the edges of the window
  133.     blitRect.left = blitRect.top = 0;
  134.     blitRect.right = theFrame->width;
  135.     blitRect.bottom = theFrame->height;
  136.  
  137.     x -= theFrame->hotX;
  138.     y -= theFrame->hotY;
  139.     
  140.     OffsetRect(&blitRect, x, y);
  141.     
  142.     if (blitRect.left < 0)
  143.         h = -blitRect.left;
  144.  
  145.     if (blitRect.left > dest->portRect.right)
  146.         return (emptyRect);
  147.         
  148.     if (blitRect.top < 0)
  149.         v = -blitRect.top;
  150.  
  151.     if (blitRect.top > dest->portRect.bottom)
  152.         return (emptyRect);
  153.         
  154.     if (blitRect.right > dest->portRect.right)
  155.         blitRect.right = dest->portRect.right;
  156.  
  157.     if (blitRect.right < 0)
  158.         return (emptyRect);
  159.         
  160.     if (blitRect.bottom > dest->portRect.bottom)
  161.         blitRect.bottom = dest->portRect.bottom;
  162.  
  163.     if (blitRect.bottom < 0)
  164.         return (emptyRect);
  165.  
  166.     OffsetRect(&blitRect, -blitRect.left, -blitRect.top);
  167.     blitRect.left += h;
  168.     blitRect.top += v;
  169.  
  170.     //•    Blit the clipped area to the screen
  171.     TransBitBlit(theFrame->image + (blitRect.top * theFrame->width) + blitRect.left, dest,
  172.         blitRect.right - blitRect.left, blitRect.bottom - blitRect.top, theFrame->width,
  173.         x + h, y + v);
  174.  
  175.     OffsetRect(&blitRect, x, y);
  176.     
  177.     return (blitRect);
  178. }
  179.  
  180. //•    --------------------    SpriteDispose
  181.  
  182. void
  183. SpriteDispose(SpritePtr *theSprite)
  184. {
  185. UInt32    i;
  186.  
  187.     if (! *theSprite)
  188.         return;
  189.  
  190.     for (i = 0; i < (*theSprite)->numFrames; i++)
  191.     {
  192.         DisposeTaggedPtrZ((Ptr *) &(*theSprite)->frames[i]->image);
  193.         DisposeTaggedPtrZ((Ptr *) &(*theSprite)->frames[i]);
  194.     }
  195.  
  196.     DisposeTaggedPtrZ((Ptr *) &(*theSprite)->frames);
  197.     DisposeTaggedPtrZ((Ptr *) theSprite);
  198. }
  199.  
  200. //•    --------------------    SpriteHeight
  201.  
  202. UInt16
  203. SpriteHeight(SpritePtr whichSprite, UInt16 whichFrame)
  204. {
  205.     if (whichFrame > (whichSprite->numFrames - 1))
  206.         return (0);
  207.         
  208.     return (whichSprite->frames[whichFrame]->height);
  209. }
  210.  
  211. //•    --------------------    SpriteWidth
  212.  
  213. UInt16
  214. SpriteWidth(SpritePtr whichSprite, UInt16 whichFrame)
  215. {
  216.     if (whichFrame > (whichSprite->numFrames - 1))
  217.         return (0);
  218.         
  219.     return (whichSprite->frames[whichFrame]->width);
  220. }
  221.  
  222. //•    --------------------    IntersectRects
  223.  
  224. Boolean
  225. IntersectRects(const RectPtr a, const RectPtr b)
  226. {
  227.     if (b->right < a->left)
  228.         return (false);
  229.         
  230.     if (b->left > a->right)
  231.         return (false);
  232.         
  233.     if (b->top > a->bottom)
  234.         return (false);
  235.         
  236.     if (b->bottom < a->top)
  237.         return (false);
  238.         
  239.     return (true);
  240. }